package daoImpl;

import java.util.ArrayList;
import java.util.Collection;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import util.HibernateUtil;
import dao.ProdutoDao;
import entities.Produto;
import entities.TipoProduto;

public class ProdutoDaoImpl implements ProdutoDao {

	private static Logger log = Logger.getLogger(ProdutoDaoImpl.class);
	
	private static ProdutoDao produtoDaoImpl = null;

	public static ProdutoDao getInstance(){
		if(produtoDaoImpl == null){
			produtoDaoImpl = new ProdutoDaoImpl();			
		}

		return produtoDaoImpl;
	}

	
	
	@Override
	public void cadastrarTipoProduto(TipoProduto tipo)
			throws HibernateException {
		log.debug("Inicio do metodo ProdutoDAOImpl.cadastrarProdutos. Iniciando o " +
				"cadastro dos seguintes dados: " + tipo);


		Session session =  HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();

		try{
			session.saveOrUpdate(tipo);
			tx.commit();
		}
		catch(HibernateException e){
			log.error(e);
			tx.rollback();
			throw e;
		}
		finally{
			session.close();
		}

	}
	
	@Override
	public void cadastrarProdutos(Collection<Produto> produtos)
			throws HibernateException {
//		log.debug("Inicio do metodo ProdutoDAOImpl.cadastrarProdutos. Iniciando o " +
//				"cadastro dos seguintes dados: " + produtos);


		Session session =  HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();

		try{
			
			session.saveOrUpdate(produtos);
			tx.commit();
		}
		catch(HibernateException e){
			log.error(e);
			tx.rollback();
			throw e;
		}
		finally{
			session.close();
		}

	}

	@Override
	public ArrayList<String> getAllCategorias() throws HibernateException {
		log.debug("Inicio do metodo ProdutoDAOImpl.getAllCategorias.");

		Session session =  HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();

		ArrayList<String> retorno = new ArrayList<String>();
		
		try{
			
			Criteria criteria = session.createCriteria(TipoProduto.class)
			.addOrder(Order.asc("tipo"))
			.setProjection(Projections.distinct(Projections.property("tipo")));
			
			return (ArrayList<String>) criteria.list(); 

		}
		catch(HibernateException e){
			log.error(e);
			tx.rollback();
			throw e;
		}
		finally{
			session.close();
		}
	}
	
	@Override
	public ArrayList<String> getAllNameProdutosOfCateg(String tipo) throws HibernateException {
		log.debug("Inicio do metodo ProdutoDAOImpl.getAllProdutosOfCateg.");

		Session session =  HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();

		try{
			
			Criteria criteria = session.createCriteria(TipoProduto.class)
			.addOrder(Order.asc("nome"))  
			.add(Restrictions.ilike("tipo", tipo))
			.setProjection(Projections.property("nome"));
			
			return (ArrayList<String>) criteria.list(); 

		}
		catch(HibernateException e){
			log.error(e);
			tx.rollback();
			throw e;
		}
		finally{
			session.close();
		}
	}
	
	@Override
	public Collection<Produto> getAllProdutosDisponiveis() throws HibernateException {
		log.debug("Inicio do metodo VendasDaoImpl.getAllProdutosDisponiveis");

		Session session =  HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();

		try{
			
			Criteria criteria = session.createCriteria(Produto.class)
			.addOrder(Order.asc("nome"))  
			.add(Restrictions.eq("vendido", false));
			
			return criteria.list(); 

		}
		catch(HibernateException e){
			log.error(e);
			tx.rollback();
			throw e;
		}
		finally{
			session.close();
		}
	}
}
